package com.linphone.demo;
import static android.content.Intent.ACTION_MAIN;

import java.util.List;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCall.State;
import org.linphone.core.LinphoneCallParams;
import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneProxyConfig;
import org.linphone.mediastream.Log;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.linphone.demo.library.LinphoneManager;
import com.linphone.demo.library.LinphonePreferences;
import com.linphone.demo.library.LinphoneService;
import com.linphone.demo.library.LinphoneSimpleListener.LinphoneOnCallStateChangedListener;
import com.linphone.demo.library.LinphoneUtils;
import com.linphone.demo.video.VideoCallActivity;
public class MainActivity extends Activity implements OnClickListener , LinphoneOnCallStateChangedListener{

	private EditText edit_username;
	private Button btn_login;
	private Button btn_login_static;
	private Button btn_logout;
	private TextView txt_info;
	
	private Button btn_call;
	private Button btn_video;
	private EditText edit_friend;
	private Button btn_accept;
	private Button btn_stop;
	
	private LinphonePreferences mPrefs;
	private Handler mHandler;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.act_main);
		mPrefs = LinphonePreferences.instance();
		mHandler = new Handler();
		initView();
	}

	private void initView() {
		edit_username = (EditText) findViewById(R.id.edit_username);
		txt_info = (TextView ) findViewById(R.id.txt_info);
		edit_friend = (EditText) findViewById(R.id.edit_friend);
		
		btn_login = (Button) findViewById(R.id.btn_login);
		btn_login_static = (Button) findViewById(R.id.btn_login_static);
		btn_logout = (Button) findViewById(R.id.btn_logout);
		btn_logout.setOnClickListener(this);
		btn_login.setOnClickListener(this);
		btn_login_static.setOnClickListener(this);
		
		btn_call = (Button ) findViewById(R.id.btn_call);
		btn_video = (Button) findViewById(R.id.btn_video);
		
		btn_call.setOnClickListener(this);
		btn_video.setOnClickListener(this);
		
		btn_accept = (Button) findViewById(R.id.btn_accept);
		btn_stop = (Button) findViewById(R.id.btn_stop);
		btn_accept.setOnClickListener(this);
		btn_stop.setOnClickListener(this);
	}

	@Override
	protected void onResume() {
		super.onResume();
		if(!LinphoneService.isReady()){
			startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
		}
	}
	
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.btn_login:
			if(edit_username.getText() == null){
				return ;
			}
			String username = edit_username.getText().toString().trim();
			if(username == null || username.equals("")){
				return;
			}
			
			saveCreatedAccount(username, "88888888", "202.67.195.123:8888");
			if (LinphoneManager.getLc().getDefaultProxyConfig() != null) {
				txt_info.setText("login progress \n");
			}
			break;

		case R.id.btn_login_static:
			String username_static = edit_username.getText().toString().trim();
			updateAccountLed(username_static, "202.67.195.123");
			break;
			
		case R.id.btn_logout:
			mPrefs.deleteAccount(0);
			break;
			
		case R.id.btn_call:
			String friend_call = edit_friend.getText().toString().trim();
			if(friend_call == null || "".equals(friend_call)){
				Toast.makeText(getApplicationContext(), "Number is Empty", Toast.LENGTH_SHORT).show();
				return;
			}
			mPrefs.enableVideo(false);
			mPrefs.setInitiateVideoCall(false);
			mPrefs.setAutomaticallyAcceptVideoRequests(false);
			
			LinphoneManager.getInstance().newOutgoingCall(friend_call, null);	
			
			break;
			
		case R.id.btn_video:
			String friend_video = edit_friend.getText().toString().trim();
			if(friend_video == null || "".equals(friend_video)){
				Toast.makeText(getApplicationContext(), "Number is Empty", Toast.LENGTH_SHORT).show();
				return;
			}
			
			mPrefs.enableVideo(true);
			mPrefs.setInitiateVideoCall(true);
			mPrefs.setAutomaticallyAcceptVideoRequests(true);
			LinphoneManager.getInstance().newOutgoingCall(friend_video, null);
			
			startActivity(new Intent(getApplicationContext(), VideoCallActivity.class));
			break;
			
		case R.id.btn_accept:
			InComingCall(true);
			
			break;
			
		case R.id.btn_stop:
			InComingCall(false);
			
			break;
		default:
			break;
		}
	}
	
	/**
	 * 登录
	 * @param username
	 * @param password
	 * @param domain
	 */
	public void saveCreatedAccount(String username, String password, String domain) {
		mPrefs.setNewAccountUsername(username);
		mPrefs.setNewAccountDomain(domain);
		mPrefs.setNewAccountPassword(password);
		try {
			mPrefs.saveNewAccount();
		} catch (LinphoneCoreException e) { 
			e.printStackTrace();
		}
	}
	
	/**
	 * 循环监听在线状态
	 * @param username
	 * @param domain
	 */
	private void updateAccountLed(final String username, final String domain) {
		
		if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) {
			for (LinphoneProxyConfig lpc : LinphoneManager.getLc().getProxyConfigList()) {
				LinphoneAddress addr = null;
				try {
					addr = LinphoneCoreFactory.instance().createLinphoneAddress(lpc.getIdentity());
				} catch (LinphoneCoreException e) {
					txt_info.setText("login error \n");
					return;
				}
				if (addr.getUserName().equals(username) && addr.getDomain().equals(domain)) {
					if (lpc.getState() == LinphoneCore.RegistrationState.RegistrationOk) {
						txt_info.setText("login succes \n");
					} else if (lpc.getState() == LinphoneCore.RegistrationState.RegistrationFailed) {
						txt_info.setText("login error \n");
					} else if (lpc.getState() == LinphoneCore.RegistrationState.RegistrationProgress) {
						txt_info.setText("login progress \n");
						mHandler.postDelayed(new Runnable() {
							@Override
							public void run() {
								updateAccountLed(username, domain);
							}
						}, 500);
					} else {
						txt_info.setText("login error \n");
					}
					break;
				}
			}
		}
	}
	
	private LinphoneCall mCall;
	public void InComingCall(boolean isAccept ){
		if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) {
			List<LinphoneCall> calls = LinphoneUtils.getLinphoneCalls(LinphoneManager.getLc());
			for (LinphoneCall call : calls) {
				if (State.IncomingReceived == call.getState()) {
					mCall = call;
					break;
				}
			}
		}
		
		if(mCall != null){
			if(isAccept){
				LinphoneCallParams params = LinphoneManager.getLc().createDefaultCallParameters();
				if (mCall != null && mCall.getRemoteParams() != null && mCall.getRemoteParams().getVideoEnabled() && LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()) {
					params.setVideoEnabled(true);
				} else {
					params.setVideoEnabled(false);
				}
				
				boolean isLowBandwidthConnection = !LinphoneUtils.isHightBandwidthConnection(this);
				if (isLowBandwidthConnection) {
					params.enableLowBandwidth(true);
					Log.d("Low bandwidth enabled in call params");
				}
				
				LinphoneManager.getInstance().acceptCallWithParams(mCall, params);
			}else{
//				LinphoneManager.getLc().terminateCall(mCall);
				
				LinphoneCore lc = LinphoneManager.getLc();
				LinphoneCall currentCall = lc.getCurrentCall();
				
				if (currentCall != null) {
					lc.terminateCall(currentCall);
				} else if (lc.isInConference()) {
					lc.terminateConference();
				} else {
					lc.terminateAllCalls();
				}
				
			}
		}
	}

	@Override
	public void onCallStateChanged(LinphoneCall call, State state,
			String message) {
		txt_info.setText(call.getRemoteAddress().getUserName()+" --> "+ state.toString()+" | "+message);
	}
	
}
